package com.springboot.demo.io.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.springboot.demo.io.Constants;

/**
 * AIO服务
 * <p>
 * AIO 也叫NIO2.0 是一种非阻塞异步的通信模式。在NIO的基础上引入了新的异步通道的概念，并提供了异步文件通道和异步套接字通道的实现。
 * AIO 并没有采用NIO的多路复用器，而是使用异步通道的概念。其read，write方法的返回类型都是Future对象,而Future模型是异步的，
 * 其核心思想是：去主函数等待时间
 * <p>
 * 小结：AIO模型中通过AsynchronousSocketChannel和AsynchronousServerSocketChannel完成套接字通道的实现。非阻塞，异步。
 *
 * @author supu
 * @date 2019-12-03 17:03
 **/
public class AIOServer {
    // 线程池
    private ExecutorService executorService;
    // 通道组
    private AsynchronousChannelGroup channelGroup;
    // 服务器通道
    public AsynchronousServerSocketChannel serverSocketChannel;

    public AIOServer() {
    }

    public void startAIOServer() {
        try {
            // 1、创建一个缓存线程池
            executorService = Executors.newCachedThreadPool();
            // 2、创建通道组
            channelGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
            // 3、创建服务器通道
            serverSocketChannel = AsynchronousServerSocketChannel.open(channelGroup);
            // 4、绑定网络
            serverSocketChannel.bind(new InetSocketAddress(Constants.AIO_PORT));
            System.out.println("AIO server starting......");
            // 等待客户端请求
            serverSocketChannel.accept(this, new AIOServerHandler());
            // 一直阻塞 不让服务器停止，真实环境是在tomcat下运行，所以不需要这行代码
            TimeUnit.MILLISECONDS.sleep(Integer.MAX_VALUE);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new AIOServer().startAIOServer();
    }
}
